/**
 * 
 */
package com.nari.baseinfo.dao;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.nari.baseinfo.model.IProject;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-1
 */
public class ProjectDaoImpl extends GenericDaoImpl<IProject, String> implements IProjectDao {
	private IResourceAccessControlDao iResourceAccessControlDao;

	/**
	 * 分页查询项目列表
	 * @param projectID 项目编号(可选)
	 * @param projectName 项目名称(可选)
	 * @param capitalCityID 所属市级机构ID(可选)
	 * @param provinceCityID 所属省级机构ID(可选)
	 * @param projDate 施工日期(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-5
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IProject> queryProjectWithPageCond(String projectID, 
			String projectName, String capitalCityID, String provinceCityID, Date projDate, 
			PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IProject.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IProject.class);
		// 项目编号
		if (projectID != null && !"".equals(projectID.trim())) {
			listCriteria.add(Restrictions.ilike("projectID", projectID.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("projectID", projectID.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		// 项目名称
		if (projectName != null && !"".equals(projectName.trim())) {
			listCriteria.add(Restrictions.ilike("projectName", projectName.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("projectName", projectName.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		// 所属市级机构
		if (capitalCityID != null && !"".equals(capitalCityID.trim())) {
			listCriteria.add(Restrictions.eq("capitalCityID", capitalCityID.trim()));
			countCriteria.add(Restrictions.eq("capitalCityID", capitalCityID.trim()));
		}
		// 所属省级机构
		if (provinceCityID != null && !"".equals(provinceCityID.trim())) {
			listCriteria.add(Restrictions.eq("provinceCityID", provinceCityID.trim()));
			countCriteria.add(Restrictions.eq("provinceCityID", provinceCityID.trim()));
		}
		// 施工日期
		if (projDate != null) {
			listCriteria.add(Restrictions.eq("projDate", projDate));
			countCriteria.add(Restrictions.eq("projDate", projDate));
		}
		// 统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		// 结果集排序
		listCriteria.addOrder(Order.asc("projectID")).addOrder(Order.desc("projDate"));
		// 结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		// 构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IProject> projectPage = new ResultWithPageCond<IProject>();
		projectPage.setList(listCriteria.list());
		projectPage.setPageCond(pageCond);
		return projectPage;
	}
	
	/**
	 * 分页查询项目列表
	 * @param projectID 项目编号(可选)
	 * @param projectName 项目名称(可选)
	 * @param capitalCityUID 所属市级机构UID(可选)
	 * @param provinceCityUID 所属省级机构UID(可选)
	 * @param projDate 施工日期(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-14
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IProject> queryAuthorityProjectWithPageCond(String projectID, 
			String projectName, String capitalCityUID, String provinceCityUID, Date projDate, 
			PageCond pageCond) throws Exception {
		String listHql = "from IProject p where 1=1";
		// 项目编号
		if (projectID != null && !"".equals(projectID.trim())) {
			listHql += " and lower(p.projectID) like '%"+projectID.trim().toLowerCase()+"%'";
		}
		// 项目名称
		if (projectName != null && !"".equals(projectName.trim())) {
			listHql += " and lower(p.projectName) like '%"+projectName.trim().toLowerCase()+"%'";
		}
		// 所属市级机构
		if (capitalCityUID != null && !"".equals(capitalCityUID.trim())) {
			listHql += " and p.capitalCityID='"+capitalCityUID+"'";
		}
		// 所属省级机构
		if (provinceCityUID != null && !"".equals(provinceCityUID.trim())) {
			listHql += " and p.provinceCityID='"+provinceCityUID+"'";
		}
		// 施工日期
		if (projDate != null) {
			listHql += " and p.projDate=:paramDate";
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			listHql += " and p.id in("+authorityRes+")";
		}
		//统计结果集个数
		String countHql = "select count(*) " + listHql;
		Query countQuery = this.getCurrentSession().createQuery(countHql);
		if(projDate != null) {
			countQuery.setTimestamp("paramDate", projDate); //设置查询参数
		}
		int total = ((Long)countQuery.uniqueResult()).intValue();
		//列表结果集查询
		listHql += " order by p.projectID,p.projDate desc";
		Query listQuery = this.getCurrentSession().createQuery(listHql);
		if(projDate != null) {
			listQuery.setTimestamp("paramDate", projDate); //设置查询参数
		}
		listQuery.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		// 构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IProject> projectPage = new ResultWithPageCond<IProject>();
		projectPage.setList(listQuery.list());
		projectPage.setPageCond(pageCond);
		return projectPage;
	}

	/**
	 * 查询所有项目信息，并对结果集排序
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-8
	 */
	public List<IProject> queryAllProjectInOrder() throws Exception {
		String hsql = "from IProject p";
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			hsql += " where p.id in("+authorityRes+")";
		}
		hsql += " order by p.projectID,p.projDate desc";
		return this.runQueryHSql(hsql);
	}

	/**
	 * 通过所属城市查询项目列表
	 * @param provinceCityUID 所属省级机构
	 * @param capitalCityUID 所属市级机构
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-25
	 */
	public List<IProject> queryProjectsByBelongCity(String provinceCityUID,
			String capitalCityUID) throws Exception {
		String listHql = "from IProject p where 1=1";
		// 所属市级机构
		if (capitalCityUID != null && !"".equals(capitalCityUID.trim())) {
			listHql += " and p.capitalCityID='"+capitalCityUID+"'";
		}
		// 所属省级机构
		if (provinceCityUID != null && !"".equals(provinceCityUID.trim())) {
			listHql += " and p.provinceCityID='"+provinceCityUID+"'";
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			listHql += " and p.id in("+authorityRes+")";
		}
		//列表结果集排序
		listHql += " order by p.projectID,p.projDate desc";
		return this.runQueryHSql(listHql);
	}

	/**
	 * 通过唯一标识列表查询项目信息
	 * @param idList 唯一标识列表，若为空列表，则结果集返回空
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-9
	 */
	public List<IProject> queryProjectsByIDList(List<String> idList)
			throws Exception {
		if (idList != null && idList.size() > 0) {
			StringBuffer queryHQL = new StringBuffer("select distinct p from IProject p ");
			queryHQL.append("where p.id in(");
			for (int index = 0; index < idList.size(); index++) {
				queryHQL.append("'");
				queryHQL.append(idList.get(index));
				queryHQL.append("'");
				if (index < idList.size() - 1) {
					queryHQL.append(",");
				}
			}
			queryHQL.append(") ");
			queryHQL.append("order by p.projDate desc,p.projectID");
			return this.runQueryHSql(queryHQL.toString());
		}
		return null;
	}

	/**
	 * 通过唯一标识列表查询项目id-projectName映射信息
	 * @param idList 唯一标识列表，若为空列表，则空映射
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-9
	 */
	public Map<String, String> queryProjectMapByIDList(List<String> idList) throws Exception {
		// 查询项目id-projectName列表
		List<Object> projectAttrs = null;
		if (idList != null && idList.size() > 0) {
			StringBuffer queryHQL = new StringBuffer("select distinct p.id,p.projectName ");
			queryHQL.append("from IProject p ");
			queryHQL.append("where p.id in(");
			for (int index = 0; index < idList.size(); index++) {
				queryHQL.append("'");
				queryHQL.append(idList.get(index));
				queryHQL.append("'");
				if (index < idList.size() - 1) {
					queryHQL.append(",");
				}
			}
			queryHQL.append(") ");
			queryHQL.append("order by p.projDate desc,p.projectID");
			projectAttrs = this.runQueryHSqlObject(queryHQL.toString());
		}
		// 格式化id-projectName映射关系
		Map<String, String> projectMap = new HashMap<String, String>();
		if (projectAttrs != null && projectAttrs.size() > 0) {
			for (Object attrs : projectAttrs) {
				Object[] attrArray = (Object[]) attrs;
				projectMap.put((String) attrArray[0], (String) attrArray[1]);
			}
		}
		return projectMap;
	}
	
	/**
	 * 统计项目编号重复的个数
	 * @param projectID
	 * @param projectUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-11-24
	 */
	public int countRepeatProjectIDNum(String projectID, String projectUID) throws Exception {
		String hsql = "select count(*) from IProject p " +
				"where p.projectID='"+projectID+"'";
		if(projectUID!=null && !"".equals(projectUID)) {
			hsql += " and p.id<>'"+projectUID+"'";
		}
		return ((Long)this.getCurrentSession().createQuery(hsql).uniqueResult()).intValue();
	}
	
	/**
	 * 根据项目ID级联删除关联信息
	 * 包括：项目、小区、楼栋、单元、热用户、系统用户及角色、集中器、热量表、分配表、散热器、温度点
	 * 分摊域、分摊域分摊账单、用户分摊账单
	 * 注意：热量表数据、分配表数据等表计数据具有不可恢复性，因此不能作为级联删除的对象
	 * @param projectUID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-13
	 */
	public void deleteCascadeByProjectUID(String projectUID) throws Exception {
		//删除项目所属散热器
		String delSinkerHql = "delete from PSinkInfo sink " +
				"where sink.roomId in(select hr.id " +
									"from IHeatRoom hr " +
									"where hr.projectID='"+projectUID+"')";
		this.runFormatHSql(delSinkerHql);
		//删除项目所属分配表
		String delAssignMeterHql = "delete from IAssignMeter am " +
				"where am.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.projectID='"+projectUID+"')";
		this.runFormatHSql(delAssignMeterHql);
		//删除项目所属热量表
		String delHeatMeterHql = "delete from IHeatMeter hm " +
				"where hm.projectID='"+projectUID+"'";
		this.runFormatHSql(delHeatMeterHql);
		//删除项目所属分摊域
		String delShareAreaHql = "delete from IShareArea sa " +
				"where sa.projectID='"+projectUID+"'";
		this.runFormatHSql(delShareAreaHql);
		//删除项目所属分摊账单
		String delSinkResultHql = "delete from IShareSinkResult ssr " +
				"where ssr.userShareResultID in(select usr.id " +
											"from IUserShareResult usr " +
											"where usr.projectID='"+projectUID+"')";
		this.runFormatHSql(delSinkResultHql);
		String delUserResultHql = "delete from IUserShareResult usr " +
				"where usr.projectID='"+projectUID+"'";
		this.runFormatHSql(delUserResultHql);
		String delAreaResultHql = "delete from IShareAreaResult sar " +
				"where sar.projectID='"+projectUID+"'";
		this.runFormatHSql(delAreaResultHql);
		//删除项目所属小区
		String delCommunityHql = "delete from ICommunity c " +
				"where c.projectID='"+projectUID+"'";
		this.runFormatHSql(delCommunityHql);
		//删除项目所属楼栋单元
		String delUnitHql = "delete from IBuildingUnit bu " +
				"where bu.buildingID in(select b.id " +
				 					"from IBuilding b " +
				 					"where b.projectID='"+projectUID+"')";
		this.runFormatHSql(delUnitHql);
		//删除项目所属楼栋
		String delBuildingHql = "delete from IBuilding b " +
				"where b.projectID='"+projectUID+"'";
		this.runFormatHSql(delBuildingHql);
		//删除项目所属集中器
		String delConcentratorHql = "delete from IConcentrator c " +
				"where c.projectID='"+projectUID+"'";
		this.runFormatHSql(delConcentratorHql);
		//删除项目所属的温度点
		String delTempPointHql = "delete from ITemperaturePoint tp " +
				"where tp.projectID='"+projectUID+"'";
		this.runFormatHSql(delTempPointHql);
		//删除项目所属系统用户、用户角色
		String delUserRoleHql = "delete from IUserRole ur " +
				"where ur.userUuid in(select u.id " +
									"from IUser u " +
									"where u.roomId in(select hr.id " +
													"from IHeatRoom hr " +
													"where hr.projectID='"+projectUID+"'))";
		this.runFormatHSql(delUserRoleHql);
		String deleteUserHql = "delete from IUser u " +
				"where u.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.projectID='"+projectUID+"')";
		this.runFormatHSql(deleteUserHql);
		//删除项目所属热用户
		String delRoomHql = "delete from IHeatRoom hr " +
				"where hr.projectID='"+projectUID+"'";
		this.runFormatHSql(delRoomHql);
		//删除项目信息
		String delProjectHql = "delete from IProject " +
				"p where p.id='"+projectUID+"'";
		this.runFormatHSql(delProjectHql);
	}
	
	/**
	 * 删除项目管理员
	 * @param projectUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-19
	 */
	public ResponseMsg deleteProjectManager(String projectUID) throws Exception {
		IProject project = this.queryEntityById(projectUID);
		if(project != null) {
			project.setShareAreaManager(null);
			this.updateEntity(project, projectUID);
			return ResponseMsg.getInstance(true, "");
		}
		return ResponseMsg.getInstance(false, "项目信息已不存在，无法执行更新操作！");
	}
	
	/**
	 * 设置项目管理员
	 * @param projectUID
	 * @param userUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-19
	 */
	public ResponseMsg saveProjectManager(String projectUID, String userUID) throws Exception {
		IProject project = this.queryEntityById(projectUID);
		if(project != null) {
			project.setShareAreaManager(userUID);
			this.updateEntity(project, projectUID);
			return ResponseMsg.getInstance(true, "");
		}
		return ResponseMsg.getInstance(false, "项目信息已不存在，无法执行更新操作！");
	}

	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}

}
